<template>
  <div v-if="visible" class="game-over-overlay">
    <div class="game-over-dialog">
      <div class="dialog-header">
        <h2 class="dialog-title">🎉 游戏结束!</h2>
        <p class="dialog-subtitle">Territory Paint Battle</p>
        <img v-if="topPlayer" class="victory-anim" :src="headerImg" alt="result" />
      </div>
      
      <div class="results-section">
        <h3>最终排名与经验结算</h3>
        <div class="final-rankings">
          <div 
            v-for="(player, index) in sortedPlayers" 
            :key="player.name"
            class="ranking-item"
            :class="{ 
              'winner': index === 0,
              'current-player': isMe(player)
            }"
          >
            <div class="rank-number">{{ index + 1 }}</div>
            <div 
              class="player-color"
              :style="{ backgroundColor: player.color }"
            ></div>
            <div class="player-info">
              <span class="player-name">{{ player.name }}</span>
              <span class="player-score">{{ player.score }}%</span>
            </div>
            <div class="winner-badge" v-if="index === 0">🏆</div>
            <div class="exp-info">
              <span class="exp-label">+{{ getExpFor(player, index) }} EXP</span>
            </div>
          </div>
        </div>
      </div>
      
      <div class="stats-summary">
        <div class="stat-item">
          <span class="stat-label">总涂色面积:</span>
          <span class="stat-value">{{ totalPixels }} 像素</span>
        </div>
        <div class="stat-item">
          <span class="stat-label">游戏时长:</span>
          <span class="stat-value">{{ gameDuration }}</span>
        </div>
      </div>
      
      <div class="dialog-actions">
        <button class="btn btn-primary" @click="confirmAndBack">
          返回大厅
        </button>
      </div>
    </div>
  </div>
</template>

<script>
import { computed, onMounted, watch } from 'vue'
import { useRouter } from 'vue-router'
import { useGameStore } from '@/stores/game'
import { useUserStore } from '@/stores/user'
import { userLevelAPI } from '@/api'
import victoryImg from '@/assets/images/胜利.webp'
import defeatImg from '@/assets/images/惜败.webp'
import victorySfx from '@/assets/audio/胜利音效.mp3'
import defeatSfx from '@/assets/audio/惜败音效.mp3'

export default {
  name: 'GameOverDialog',
  // 输入：是否展示对话框
  props: {
    visible: { type: Boolean, default: false }
  },
  // 输出：重新开始事件（通知父级重启计时等）
  emits: [],
  setup(props) {
    const router = useRouter()
    const gameStore = useGameStore()
    
    // 从 store 计算得到排序后的玩家、总像素与本局用时摘要
    const sortedPlayers = computed(() => gameStore.sortedPlayers)
    const topPlayer = computed(() => (sortedPlayers.value && sortedPlayers.value.length ? sortedPlayers.value[0] : null))
    const totalPixels = computed(() => Object.keys(gameStore.canvasData.pixels).length)
    const gameDuration = computed(() => {
      // 使用gameStore中的实际游戏总时长，而不是硬编码的120秒
      const totalSeconds = gameStore.gameTotalDuration - gameStore.gameTime
      const minutes = Math.floor(totalSeconds / 60)
      const seconds = totalSeconds % 60
      return `${minutes}分${seconds}秒`
    })
    
    // 播放胜利音效（对第一名）
    let victoryAudio, defeatAudio
    const playVictory = () => {
      try {
        if (!victoryAudio) victoryAudio = new Audio(victorySfx)
        victoryAudio.currentTime = 0
        victoryAudio.play().catch(() => {})
      } catch (_) {}
    }
    const playDefeat = () => {
      try {
        if (!defeatAudio) defeatAudio = new Audio(defeatSfx)
        defeatAudio.currentTime = 0
        defeatAudio.play().catch(() => {})
      } catch (_) {}
    }
    const userStore = useUserStore()
    const isMe = (player) => {
      const me = (userStore.user?.userName || userStore.user?.UserName || userStore.user?.name)
      return me ? String(player?.name) === String(me) : false
    }
    onMounted(() => { if (props.visible) triggerAudioPerUser() })
    watch(() => props.visible, v => { if (v) triggerAudioPerUser() })
    const triggerAudioPerUser = () => {
      try {
        if (!sortedPlayers.value || sortedPlayers.value.length === 0) return
        const me = sortedPlayers.value.find(p => isMe(p))
        if (!me) return
        const myIndex = sortedPlayers.value.findIndex(p => p.name === me.name)
        if (myIndex === 0) {
          playVictory()
        } else {
          playDefeat()
        }
      } catch (_) {}
    }
    
    const goHome = () => {
      router.push('/')
    }
    
    const confirmAndBack = async () => {
      try {
        // 结束本地游戏状态
        gameStore.endGame()
        // 返回大厅
        router.push('/')
      } catch (_) {}
    }
    
    // 头图：按当前用户名次展示，第一名显示胜利动画，其它显示惜败
    const myIndex = computed(() => {
      try {
        const me = (userStore.user?.userName || userStore.user?.UserName || userStore.user?.name)
        if (!me || !sortedPlayers.value || sortedPlayers.value.length === 0) return -1
        return sortedPlayers.value.findIndex(p => String(p.name) === String(me))
      } catch (_) { return -1 }
    })
    const headerImg = computed(() => (myIndex.value === 0 ? victoryImg : defeatImg))
    
    // 经验结算规则（与后端 RoomsController.EndGame 注释一致的近似规则，仅用于前端展示）
    const getExpFor = (player, index) => {
      try {
        const playerCount = sortedPlayers.value.length || 1
        const isWin = index === 0
        const base = 20
        const timeBonus = 60 // 暂以固定展示，后端实际会按时长细化
        const resultBonus = isWin ? 100 : 30
        const areaBonus = Math.min(Math.floor((player.area || 0) / 50), 200)
        const playerBonus = playerCount >= 5 ? 40 : playerCount === 4 ? 30 : playerCount === 3 ? 20 : playerCount === 2 ? 10 : 0
        const exp = Math.min(base + timeBonus + resultBonus + areaBonus + playerBonus, 500)
        return exp
      } catch (_) {
        return 50
      }
    }
    
    // 弹窗展示时为“我”调用加经验API（后端也在结束接口里做结算；这里仅作前端补偿/展示一致化）
    const settleMyExperience = async () => {
      try {
        const me = sortedPlayers.value?.find(p => isMe(p))
        if (!me) return
        const myIndex = sortedPlayers.value.findIndex(p => p.name === me.name)
        const exp = getExpFor(me, myIndex)
        const uid = useUserStore().user?.id || useUserStore().user?.userId
        if (!uid) return
        await userLevelAPI.addExperience({ userId: uid, experience: exp }, { meta: { silent: true } })
      } catch (_) {}
    }
    watch(() => props.visible, v => { if (v) settleMyExperience() })
    onMounted(() => { if (props.visible) settleMyExperience() })
    
    return { sortedPlayers, totalPixels, gameDuration, goHome, confirmAndBack, victoryImg, defeatImg, headerImg, topPlayer, isMe, getExpFor }
  }
}
</script>

<style scoped>
.game-over-overlay { position: fixed; top: 0; left: 0; right: 0; bottom: 0; background-color: rgba(0, 0, 0, 0.7); display: flex; align-items: center; justify-content: center; z-index: 1000; }
.game-over-dialog { background: white; border-radius: 16px; padding: 30px; max-width: 500px; width: 90%; max-height: 80vh; overflow-y: auto; box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04); }
.dialog-header { text-align: center; margin-bottom: 30px; }
.dialog-title { font-size: 32px; font-weight: bold; margin: 0 0 5px 0; color: #1F2937; }
.dialog-subtitle { font-size: 16px; color: #6B7280; margin: 0; }
.victory-anim { width: 120px; height: auto; display: block; margin: 10px auto 0 auto; }
.results-section { margin-bottom: 30px; }
.results-section h3 { font-size: 20px; font-weight: bold; margin: 0 0 20px 0; color: #374151; text-align: center; }
.final-rankings { display: flex; flex-direction: column; gap: 12px; }
.ranking-item { display: flex; align-items: center; gap: 15px; padding: 15px; border-radius: 12px; background-color: #F9FAFB; border: 2px solid transparent; position: relative; transition: all 0.3s ease; }
.ranking-item.winner { background: linear-gradient(135deg, #FEF3C7 0%, #FDE68A 100%); border-color: #F59E0B; transform: scale(1.02); }
.ranking-item.current-player { border-color: #3B82F6; background-color: #EFF6FF; }
.rank-number { width: 30px; height: 30px; border-radius: 50%; background-color: #E5E7EB; display: flex; align-items: center; justify-content: center; font-weight: bold; color: #374151; font-size: 14px; }
.ranking-item.winner .rank-number { background-color: #F59E0B; color: white; }
.player-color { width: 20px; height: 20px; border-radius: 50%; border: 2px solid white; box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); }
.player-info { flex: 1; display: flex; justify-content: space-between; align-items: center; }
.player-name { font-weight: 600; color: #374151; font-size: 16px; }
.player-score { font-weight: bold; color: #1F2937; font-size: 18px; }
.exp-info { margin-left: 8px; font-weight: 700; color: #065f46; }
.winner-badge { font-size: 24px; margin-left: 10px; }
.lose-anim { width: 24px; height: 24px; margin-left: 6px; opacity: .9; }
.stats-summary { background-color: #F3F4F6; border-radius: 8px; padding: 20px; margin-bottom: 30px; }
.stat-item { display: flex; justify-content: space-between; align-items: center; margin-bottom: 10px; }
.stat-item:last-child { margin-bottom: 0; }
.stat-label { color: #6B7280; font-weight: 500; }
.stat-value { color: #374151; font-weight: bold; }
.dialog-actions { display: flex; gap: 15px; justify-content: center; }
.btn { padding: 12px 24px; border: none; border-radius: 8px; font-weight: 600; cursor: pointer; transition: all 0.3s ease; font-size: 16px; }
.btn-primary { background-color: #3B82F6; color: white; }
.btn-primary:hover { background-color: #2563EB; transform: translateY(-2px); }
.btn-secondary { background-color: #F3F4F6; color: #374151; }
.btn-secondary:hover { background-color: #E5E7EB; transform: translateY(-2px); }
@media (max-width: 600px) { .game-over-dialog { padding: 20px; margin: 20px; } .dialog-title { font-size: 24px; } .dialog-actions { flex-direction: column; } .btn { width: 100%; } }
</style> 